package controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import bean.Customer;
import bean.Fund;
import bean.FundTransaction;
import bean.Model;
import bean.UserType;
import dao.FundDAO;
import dao.FundPriceHistoryDAO;
import dao.FundTransactionDAO;
import formBean.TransitionDayForm;

public class TransitionDayAction extends Action {
	private FundDAO fundDAO;
	private FundPriceHistoryDAO fundPriceHistoryDAO;
	private FundTransactionDAO fundTransactionDAO;
	
	public TransitionDayAction(Model model) {
		this.fundDAO = model.getFundDAO();
		this.fundPriceHistoryDAO = model.getFundPriceHistoryDAO();
		this.fundTransactionDAO = model.getFundTransactionDAO();
	}
	
	@Override
	public String getName() {
		return "transitionDay.do";
	}

	@Override
	public String perform(HttpServletRequest request) {
		ArrayList<String> errors = new ArrayList<String>();
		request.setAttribute("errors", errors);
		
		try {
			TransitionDayForm form = new TransitionDayForm(request);
			request.setAttribute("form", form);
			
			List<Fund> list = fundDAO.getAllFund();
			request.setAttribute("items", list);

			Date lastOrderDate = fundTransactionDAO.getLatestOrderDate();
			Date lastExecuteDate = getLasterDate(fundPriceHistoryDAO.getLatestDate(), fundTransactionDAO.getLatestExecuteDate());
					
			if (!form.isPresent()) {								
				return "transitionDay.jsp";
			}											
			
			errors.addAll(form.getValidationErrors(list, lastExecuteDate, lastOrderDate));
			
			if (errors.size() > 0) {
				return "transitionDay.jsp";
			}
			
			errors.addAll(fundPriceHistoryDAO.transitionDayPrice(form, list));
			
			if (errors.size() > 0) {
				return "transitionDay.jsp";
			}
			
			errors.addAll(executePendingTransaction(form));
			
			if (errors.size() > 0) {
				request.setAttribute("message", "The prices have been successfully set up. But the pending transactions have some problems.");
				return "employeeConsole.jsp";
			}
			
			request.setAttribute("message", "You have successfully execute the transition day.");
			return "employeeConsole.jsp";
		} catch (Exception e) {
			e.printStackTrace();
			errors.add(e.getMessage());
			return "transitionDay.jsp";
		}		
	}

	/*
	 * Should all be rejected 
	 */
	private String handleTransactionErrors(List<FundTransaction> list) {
		//The 
//		for(FundTransaction transaction:list)
//		{
//			if(transaction.getExecuteDate() == null)
//			{
//				rejected.add(transaction);
//			}
//		}
		this.fundTransactionDAO.rejectTransactions(list);
		return "transitionDay.jsp";
	}

	private ArrayList<String> executePendingTransaction(TransitionDayForm form) {
		ArrayList<String> errors = new ArrayList<String>();	
		
		List<Customer> customers = fundTransactionDAO.getPendingCustomers();
		
		List<FundTransaction> rejected = new ArrayList<FundTransaction>();
		for (Customer c : customers) {
			List<FundTransaction> pendingTrans = fundTransactionDAO.getPendingTransactionByCustomer(c);
			
			List<String> currentErrors = new ArrayList<String>();
			currentErrors.addAll(fundTransactionDAO.executeTransactions(pendingTrans, form));
			errors.addAll(currentErrors);
			if(currentErrors.size()>0 && pendingTrans != null) rejected.addAll(pendingTrans);
		}
		if(errors.size()>0)
		{
			handleTransactionErrors(rejected);
		}
		return errors;
	}
	
	private Date getLasterDate(Date date1, Date date2) {
		if (date1 == null && date2 == null) return null;
		if (date1 == null) return date2;
		if (date2 == null) return date1;
		
		return (date1.after(date2)? date1 : date2);
	}
	
	@Override
	public UserType getType() {		
		return UserType.Employee;
	}
	
}
